package com.yayan.xh.service;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.ServletWebRequest;

import com.alibaba.fastjson.JSONObject;
import com.yayan.util.DataConvertUtil;
import com.yayan.util.FilePathUtil;
import com.yayan.util.PraseXmlUtil;
import com.yayan.util.RequestUtil;
import com.yayan.xh.dao.EnterDao;
import com.yayan.xh.dao.EnterDetailDao;
import com.yayan.xh.dao.IEnterDao;
import com.yayan.xh.dao.IEnterDetailDao;
import com.yayan.xh.dao.IIntegralDao;
import com.yayan.xh.dao.IMemberDao;
import com.yayan.xh.dao.IOrderDao;
import com.yayan.xh.dao.IProductDao;
import com.yayan.xh.dao.IShopDao;
import com.yayan.xh.dao.IntegralDao;
import com.yayan.xh.dao.MemberDao;
import com.yayan.xh.dao.OrderDao;
import com.yayan.xh.dao.ProductDao;
import com.yayan.xh.dao.ShopDao;

import utils.RequestHandler;
import utils.Sha1Util;

@Service
public class OrderService implements IOrderService{
	
	private IProductDao productDao;
	
	private IIntegralDao integralDao;
	
	private IOrderDao orderDao;
	
	private IShopDao shopDao;
	
	private IMemberDao memberDao;
	
	private IEnterDao enterDao;
	
	private IEnterDetailDao enterDetailDao;
	
	public OrderService() {
		productDao = new ProductDao();
		integralDao = new IntegralDao();
		orderDao = new OrderDao();
		shopDao = new ShopDao();
		memberDao = new MemberDao();
		enterDao = new EnterDao();
		enterDetailDao = new EnterDetailDao();
	}
	
	@Override
	public Map<String, String> saveOrder(Map<String, String> map) {
		SortedMap<String, String> finalpackage = new TreeMap<String, String>();
		try {
			if(null != map.get("matchId") && null != map.get("productId") && null != map.get("totalMoney")
					&& !"0".equalsIgnoreCase(map.get("matchId")) && !"0".equalsIgnoreCase(map.get("productId")) 
					&& !"0".equalsIgnoreCase(map.get("totalMoney"))) {
				HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
				ServletWebRequest servletWebRequest = new ServletWebRequest(request);
				HttpServletResponse response = servletWebRequest.getResponse();
				//内部编号
				map.put("insideorder",System.currentTimeMillis() + "");
				//产品名称
				Map<String, Object> products = productDao.getProductByProId(map);
				map.put("productName", products.get("p_name").toString());
				//产品单价
				map.put("productPrice", products.get("p_price").toString());
				//优惠金额
				//获取用户优惠折扣
				Map<String, Object> userSale = integralDao.getUserSale(map);
				map.put("productSale", 
						(Double.parseDouble(products.get("p_price").toString()) 
								* Double.parseDouble(userSale.get("sale").toString())) + "");
				//产品总价
				map.put("productTotal", 
						Double.parseDouble(products.get("p_price").toString().toString()) 
						- Double.parseDouble(map.get("productSale").toString()) + "" );
				//产品类型
				map.put("productType", products.get("p_type").toString());
				//订单保存数据库
				if(orderDao.saveOrder(map)) {
					//生成预支付订单
					//获取商家信息
					Map<String, Object> shopMap = shopDao.getShopByShopId(map);
					//获取会员信息
					Map<String, Object> userMap = memberDao.getMemberByUid(map);
					//支付金额
					String finalmoney = String.format("%.2f", Double.parseDouble(map.get("productTotal").toString()));
					finalmoney = finalmoney.replace(".", "");
					Integer total_fee = Integer.parseInt(finalmoney);
					//8位日期
					String strTime = DataConvertUtil.getCurrTimeDay();
					//四位随机数
					Random ne=new Random();
					String strRandom = ne.nextInt(9999 - 1000 + 1) + 1000 + "";
					//序列号（随机）
					String nonce_str = strTime + strRandom;
					//商品描述根据情况修改
					String body = products.get("p_name").toString()+"订单支付";
					//回调URL
					String notify_url = FilePathUtil.getNotifyUrl();
					//商户订单号
					//订单生成的机器 IP
					String spbill_create_ip = request.getRemoteAddr();
					String out_trade_no=map.get("insideorder")+"a"+map.get("userId")+"a"+DataConvertUtil.getCurrTime();
					SortedMap<String, String> packageParams = new TreeMap<String, String>();
					packageParams.put("appid", shopMap.get("s_appid").toString());  
					packageParams.put("mch_id", shopMap.get("s_code").toString());  
					packageParams.put("nonce_str", nonce_str);  
					packageParams.put("body", body);  
					packageParams.put("out_trade_no", out_trade_no);  
					packageParams.put("total_fee", total_fee.toString());  
					packageParams.put("spbill_create_ip", spbill_create_ip);  
					packageParams.put("notify_url", notify_url);  
					packageParams.put("trade_type", "JSAPI");  
					packageParams.put("openid", userMap.get("u_openid").toString());  

					RequestHandler reqHandler = new RequestHandler(request, response);
					reqHandler.init(shopMap.get("s_appid").toString(), shopMap.get("s_secret").toString(), shopMap.get("s_partnerkey").toString());
					
					String sign = reqHandler.createSign(packageParams);
					String xml="<xml>"+
							"<appid>"+shopMap.get("s_appid").toString()+"</appid>"+
							"<mch_id>"+shopMap.get("s_code").toString()+"</mch_id>"+
							"<nonce_str>"+nonce_str+"</nonce_str>"+
							"<sign>"+sign+"</sign>"+
							"<body><![CDATA["+body+"]]></body>"+
							"<out_trade_no>"+out_trade_no+"</out_trade_no>"+
							"<total_fee>"+total_fee+"</total_fee>"+
							"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
							"<notify_url>"+notify_url+"</notify_url>"+
							"<trade_type>JSAPI</trade_type>"+
							"<openid>"+userMap.get("u_openid")+"</openid>"+
							"</xml>";
					String prepay_id = "";
					String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
					String wxXml = RequestUtil.httpsRequest(createOrderURL, "POST", xml);
					Map<String, Object> wxXmlMap = PraseXmlUtil.parseXmlToList(wxXml);
					prepay_id = wxXmlMap.get("prepay_id").toString();
					if(prepay_id.equals("")){
						return finalpackage;
					}
					
					String timestamp = Sha1Util.getTimeStamp();
					String prepay_ids = "prepay_id="+prepay_id;
					if(wxXmlMap.get("return_code").equals("SUCCESS")) {
						finalpackage.put("appId", shopMap.get("s_appid").toString());  
						finalpackage.put("timeStamp", timestamp);  
						finalpackage.put("nonceStr", nonce_str);  
						finalpackage.put("package", prepay_ids);  
						finalpackage.put("signType", "MD5");
						String finalsign = reqHandler.createSign(finalpackage);
						finalpackage.put("paySign", finalsign);
						finalpackage.put("status", "1");
						finalpackage.remove("appId");
						
						if("1".equals(map.get("productType"))) {
							enterDetailDao.saveEnterDetail(map);
						}
						
						return finalpackage;
					} else {
						finalpackage.put("status", "0");
						finalpackage.put("message", wxXmlMap.get("return_msg").toString());
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return finalpackage;
	}

	@SuppressWarnings({ "resource", "unchecked", "rawtypes" })
	@Override
	public String backOrder(String xml) {
		String result = null;
		try {
			Map<String, Object> wxXmlMap = PraseXmlUtil.parseXmlToList(xml);
			if("SUCCESS".equals(wxXmlMap.get("return_code"))) {
				Map<String, String> paraMap = new HashMap<String, String>();
				paraMap.put("mchId", wxXmlMap.get("mch_id").toString());//微信商户号
				//金额整数 （分）
				int tf = Integer.parseInt(wxXmlMap.get("total_fee").toString());
				if(tf < 10) {
					paraMap.put("totalFee", "0.0" + wxXmlMap.get("total_fee").toString());
				} else if (tf >= 10 && tf < 100) {
					paraMap.put("totalFee", "0." + wxXmlMap.get("total_fee").toString());
				} else {
					String firstStr = wxXmlMap.get("total_fee").toString().substring(0,wxXmlMap.get("total_fee").toString().length() - 2);
					String lastStr = wxXmlMap.get("total_fee").toString().substring(wxXmlMap.get("total_fee").toString().length() - 2,wxXmlMap.get("total_fee").toString().length());
					paraMap.put("totalFee", firstStr + "." + lastStr);
				}
				paraMap.put("outsideorder", wxXmlMap.get("transaction_id").toString());//外部订单号
				String[] str = wxXmlMap.get("out_trade_no").toString().split("a");
				paraMap.put("insideorder", str[0]);//内部订单号
				paraMap.put("userId", str[1]);//用户ID
				Date date = new SimpleDateFormat("yyyyMMddHHmmss").parse(wxXmlMap.get("time_end").toString()); 
				String datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
				paraMap.put("datetime", datetime);
				
				//修改订单支付状态
				if(orderDao.updateBackOrder(paraMap)) {
					//保存报名信息
					//获得商户信息
					Map<String, Object> shopMap = shopDao.getShopByShopId(paraMap);
					paraMap.put("shopId", shopMap.get("shop_id").toString());
					
					//获取订单信息
					Map<String, Object> orderMap = orderDao.getOrderByInsider(paraMap);
					paraMap.put("productId", orderMap.get("p_id").toString());
					
					//获取产品信息
					Map<String, Object> productMap = productDao.getProductByProId(paraMap);
					paraMap.put("matchId", productMap.get("m_id").toString());
					paraMap.put("type", productMap.get("p_type").toString());
					
					//获取用户信息
					Map<String, Object> userMap = memberDao.getMemberByUid(paraMap);
					paraMap.put("nickName", userMap.get("u_nickname").toString());
					
					//请求二维码
					//获取access_token
					String getAccessToken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + shopMap.get("s_appid").toString() + "&secret=" + shopMap.get("s_secret").toString();
					String atJson = RequestUtil.httpsRequest(getAccessToken, "GET", null);
					JSONObject  jasonObject = JSONObject.parseObject(atJson);
					Map map = (Map)jasonObject;
					
					//获取二维码信息
					//封装参数，路径
//					String getCode = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + map.get("access_token").toString();
					String getCode = "https://api.weixin.qq.com/wxa/getwxacode?access_token=" + map.get("access_token").toString();
					
					Map<String, Object> codePara = new HashMap<String, Object>();
//					codePara.put("scene", productMap.get("m_id") + "aaa" + orderMap.get("u_id"));
//					codePara.put("page", "pages/manage/checkTic");
					codePara.put("path", "/pages/manage/checkTic?mId=" + productMap.get("m_id") + "&uId=" + orderMap.get("u_id"));
					
					InputStream inputStream = null;
			        OutputStream outputStream = null;
					RestTemplate rest = new RestTemplate();
					MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
					HttpEntity requestEntity = new HttpEntity(codePara, headers);
					
					//获取返回文件流 输出指定目录
			        ResponseEntity<byte[]> entity = rest.exchange(getCode, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
			        byte[] codeResult = entity.getBody();
			        inputStream = new ByteArrayInputStream(codeResult);
			        File file = new File(FilePathUtil.getCodePath() + shopMap.get("shop_id") + productMap.get("m_id") + orderMap.get("u_id") + ".jpg");
			        if (!file.exists()){
			            file.createNewFile();
			        }
			        outputStream = new FileOutputStream(file);
			        int len = 0;
			        byte[] buf = new byte[1024];
			        while ((len = inputStream.read(buf, 0, 1024)) != -1) {
			             outputStream.write(buf, 0, len);
			        }
			        outputStream.flush();
					//存放二维码地址
			        paraMap.put("code", "https://shangxikongjian.com/xh/code/upload/" + shopMap.get("shop_id") + productMap.get("m_id").toString() + orderMap.get("u_id") + ".jpg");
			        long r = enterDao.saveEnter(paraMap);
			        if(r > 0) {
			        	paraMap.put("eId", r + "");
			        	if(enterDetailDao.modifyEnterDetail(paraMap))
			        		result="<xml>"
									+ "<return_code><![CDATA[SUCCESS]]></return_code>"
									+ "<return_msg></return_msg>" 
									+ "</xml>";
			        }
				} else {
					result="<xml>"
							+ "<return_code><![CDATA[SUCCESS]]></return_code>"
							+ "<return_msg><![CDATA[repeat request]]></return_msg>" 
							+ "</xml>";
				}
			}
		} catch (Exception e) {
			result="<xml>"
					+ "<return_code><![CDATA[FAIL]]></return_code>"
					+ "<return_msg><![CDATA[data exception]]></return_msg>" 
					+ "</xml>";
			e.getMessage();
		}
		return result;
	}
}
